TCP : TCP communication

更新时间:
2024-05-13
下载文档

TCP : TCP communication

The Tcp module is based on socket module, which makes TCP communication more convenient. This module is relatively low-level, it is recommended to use the net module to operate TCP communication.

User can use the following code to import the Tcp module.

var Tcp = require('tcp');

Support

The following shows Tcp module APIs available for each permissions.

 User ModePrivilege Mode
Tcp.createServer
Tcp.createClient
Tcp.createByFd
tcp.sockFd
tcp.accept
tcp.send
tcp.sendto
tcp.recv
tcp.recvfrom
tcp.pending
tcp.shutdown
tcp.mports 
tcp.error
tcp.close
tcp.flyAway
tcp.isEOF
tcp.sockName
tcp.peerName
tcp.bindToDevice
tcp.setKeepAlive
tcp.setNoDelay
tcp.setLinger
tcp.setTTL
tcp.setReuseAddr
tcp.setIPv6Only
tcp.getState
tcp.getRecvBufferSize
tcp.getSendBufferSize
tcp.setRecvBufferSize
tcp.setSendBufferSize

Tcp Class

Tcp.createServer(sockaddr[, backlog[, dev]])

  • sockaddr {Object} Local address.
  • backlog {Integer} Number of outstanding connections. default: 5.
  • dev {String} The network interface you want to bind. default: not bind.
  • Returns: {Object} Tcp object.

sockaddr includes following items:

  • domain {Integer} Address domain: socket.AF_INET or socket.AF_INET6.
  • addr {String} Address.
  • port {Integer} Port.

Create a TCP server and bind to the specified address. If the port is 0, the system automatically assigns a port. The port number assigned by the system can be obtained through the tcp.sockName() function.

EdgerOS 1.6.5 and later versions, domain can use Tcp.AF_INET and Tcp.AF_INET6; EdgerOS 1.10.1 and later versions, The domain member can be omitted.

Example

var saddr = Tcp.sockaddr(Tcp.INADDR_ANY, 2049);
var tcp = Tcp.createServer(saddr);

Tcp.createClient(sockaddr[, timeout])

  • sockaddr {Object} Remote address.
  • timeout {Integer} Wait timeout in milliseconds. default: undefined means timeout with default connect timeout setting.
  • Returns: {Object} Tcp object.

Create a TCP client and connects to the specified remote host. Use synchronous mode.

Example

var saddr = Tcp.sockaddr('192.168.0.3', 2049);
var tcp = Tcp.createClient(saddr);
if (!tcp) {
  console.log('connect error:', sys.error());
}

Tcp.createClient(sockaddr, callback)

  • sockaddr {Object} Remote address.
  • callback {Function} Connected callback.
    • tcp {Object} Tcp object.
    • remote {Object} Remote address. EdgerOS 1.6.5 and later versions add this argument.
  • Returns: {Object} Tcp object.

Create a TCP client and connects to the specified remote host. Use asynchronous mode.

The callback function will be called when the connection is timed out and the connection is successful. At this time, the remote argument is undefined, which means the connection failed. If the EdgerOS version is lower than 1.6.5, you can determine whether the connection is successful by obtaining the TCP status.

Example

var saddr = Tcp.sockaddr('192.168.0.3', 2049);
var tcp = Tcp.createClient(saddr, (tcp, saddr) => {
  if (saddr) {
    console.log('Connected');
  }
});

while (true) {
  iosched.poll(); // callback() will called here.
}

Tcp.createByFd(sockFd)

  • sockFd {Integer} Socket file descriptor, MUST tcp socket.
  • Returns: {Object} Tcp object.

Create a tcp object with socket file descriptor, mainly used to multitasking TCP server.

Example

var tcp = Tcp.createByFd(sockFd);

Tcp Object

tcp.sockFd

  • {Integer}

The tcp object socket file descriptor. The iosched module can use this descriptor for event detection.

tcp.accept([remoteAddr[, timeout]])

  • remoteAddr {Object} Remote connector address. default: undefined (does not care).
  • timeout {Integer} Wait timeout in milliseconds. default: undefined means wait forever.
  • Returns: {Object} Tcp object.

The tcp.accept() function shall extract the first connection on the queue of tcp pending connections, and create a new tcp object. Use synchronous mode.

Example

var remoteAddr = {};
var tcpNew = tcp.accept(remoteAddr);
if (tcpNew) {
  console.log('New remote connected:', remoteAddr);
}

tcp.accept(unused, callback)

  • unused {Undefined} Asynchronous mode does not use this argument.
  • callback {Function} Remote connected callback.
    • newTcp {Object} New TCP connection.
    • remoteAddr {Object} Remote address.

The tcp.accept() function shall extract the first connection on the queue of tcp pending connections, and create a new tcp object. Use asynchronous mode.

Example

tcp.accept(undefined, (newTcp, remoteAddr) => {
  console.log('New remote connected:', remoteAddr);
});

while (true) {
  iosched.poll(); // callback() will called here.
}

tcp.send(string[, timeout])

  • string {String} String to be send.
  • timeout {Integer} Wait timeout in milliseconds. default: undefined means wait forever.
  • Returns: {Integer} The number of bytes actually sent, negative error.

The tcp.send() function shall initiate transmission of a message from the specified socket to its peer.

Example

var num = tcp.send('Hello Packet!');
if (num < 0) {
  console.log('send error:', sys.error());
}

tcp.send(buffer[, offset[, length[, timeout]]])

  • buffer {Buffer} Write data buffer.
  • offset {Integer} Buffer offset. default:0.
  • length {Integer} Write length. default:buffer.length.
  • timeout {Integer} Wait timeout in milliseconds. default: undefined means wait forever.
  • Returns: {Integer} The number of bytes actually sent, negative error.

The tcp.send() function shall initiate transmission of a message from the specified socket to its peer.

Example

var buf = new Buffer([1, 2, 3]);

var num = tcp.send(buf);
if (num < 0) {
  console.log('send error:', sys.error());
}

tcp.send(array[, timeout])

  • array {Array} Buffer array.
  • timeout {Integer} Wait timeout in milliseconds. default: undefined means wait forever.
  • Returns: {Integer} The number of bytes actually sent, negative error.

The tcp.send() function shall initiate transmission of a message from the specified socket to its peer.

Example

var buf1 = new Buffer([1, 2, 3]);
var buf2 = new Buffer([4, 5, 6]);
var num = tcp.send([buf1, buf2]);
if (num < 0) {
  console.log('send error:', sys.error());
}

tcp.sendto(remoteAddr, string[, timeout])

  • remoteAddr {Undefined} Unused.
  • string {String} String to be send.
  • timeout {Integer} Wait timeout in milliseconds. default: undefined means wait forever.
  • Returns: {Integer} The number of bytes actually sent, negative error.

Same as tcp.send(string[, timeout]).

tcp.sendto(remoteAddr, buffer[, offset[, length[, timeout]]])

  • remoteAddr {Undefined} Unused.
  • buffer {Buffer} Write data buffer.
  • offset {Integer} Buffer offset. default:0.
  • length {Integer} Write length. default:buffer.length.
  • timeout {Integer} Wait timeout in milliseconds. default: undefined means wait forever.
  • Returns: {Integer} The number of bytes actually sent, negative error.

Same as tcp.send(buffer[, offset[, length[, timeout]]]).

udp.sendto(remoteAddr, array[, timeout])

  • remoteAddr {Object} Remote address.
  • array {Array} Buffer array.
  • timeout {Integer} Wait timeout in milliseconds. default: undefined means wait forever.
  • Returns: {Integer} The number of bytes actually sent, negative error.

Same as tcp.send(array[, timeout]).

tcp.recv(buffer[, offset[, length[, timeout]]])

  • buffer {Buffer} Receive buffer.
  • offset {Integer} Buffer offset. default:0.
  • length {Integer} Receive length limit. default:buffer.length.
  • timeout {Integer} Wait timeout in milliseconds. default: undefined means wait forever.
  • Returns: {Integer} The number of bytes actually receive, negative error.

The tcp.recv() function shall receive a message from a connection-mode socket.

Example

var buf = new Buffer(1024);

var num = tcp.recv(buf);
if (num < 0) {
  console.log('recv error:', sys.error());
}

tcp.recvfrom(remoteAddr, buffer[, offset[, length[, timeout]]])

  • remoteAddr {Object} Remote address.
  • buffer {Buffer} Receive buffer.
  • offset {Integer} Buffer offset. default:0.
  • length {Integer} Receive length limit. default:buffer.length.
  • timeout {Integer} Wait timeout in milliseconds. default: undefined means wait forever.
  • Returns: {Integer} The number of bytes actually receive, negative error.

The tcp.recvfrom() function shall receive a message from a connection-mode socket.

Example

var remoteAddr = {};
var buf = new Buffer(1024);

var num = tcp.recvfrom(remoteAddr, buf);
if (num < 0) {
  console.log('recvfrom error:', sys.error());
}

tcp.pending()

  • Returns: {Integer} The number of bytes in tcp buffer.

Get the number of readable bytes in the tcp buffer.

Example

var num = tcp.pending();
if (num > 0) {
  tcp.recv(buf);
}

tcp.shutdown([how])

  • how {String} Type of shutdown. default: 'rw'.
  • Returns: {Boolean} Whether the operation was successful.

The tcp.shutdown() function shall cause all or part of a full-duplex connection on the socket associated with the file descriptor socket to be shut down.

Argument how can be:

DefinitionDescription
rDisables further receive operations.
wDisables further send operations.
rwDisables further send and receive operations.

Example

tcp.shutdown();

tcp.mports(mports)

  • mports {Integer} Number of consecutive ports to be added.

This function can set a LISTEN state tcp file descriptor for multi-port listening, starting with the port when bind(), set the number of additional listening continuous ports.

Example

var saddr = Tcp.sockaddr(Tcp.INADDR_ANY, 2049);
var tcp = Tcp.createServer(saddr);
tcp.mports(5); // add listen ports: 2050, 2051, 2052, 2053, 2054

tcp.error()

  • Returns: {Integer} Last socket errno.

Get socket error status and clears it (set to zero). most like (C language):

getsockopt(sockFd, SOL_SOCKET, SO_ERROR, (void *)&err, &len);

Example

var errno = tcp.error();
if (errno) {
  console.log('socket error:', sys.error(errno));
}

tcp.close()

Close this tcp and reclaiming file descriptors. If user forgets to call this function, the file descriptor is automatically reclaimed when the object is destroyed.

tcp.flyAway()

This function is only used in multitasking mode. Clear the object internal file descriptor and do not recycle the file descriptor. This method is used for file descriptor delivery between multitasking, to prevent system errors from reclaiming file descriptors.

Example

  • main.js
var newTcp = tcp.accept();

// Send file descriptor to other task.
Task.send(otherTask.id(), { sockFd: newTcp.sockFd });

// MUST Call flyAway() and cannot use this object again.
newTcp.flyAway();
  • task.js
var msg = Task.recv();

// Create a tcp object by sockFd.
var tcp = Tcp.createByFd(msg.sockFd);

tcp.isEOF()

  • Returns: {Boolean} Whether the TCP socket receives complete data. (EOF)

This function is used to judge whether the TCP connection has received complete data. This function must follow the recv and recvfrom functions. When these two functions return a negative number, it means that the TCP connection is disconnected. You can judge whether the reception is complete through the isEOF function. This function is valid on EdgerOS 2.0.0 and above.

Example

var num = tcp.recv(...);
if (num < 0) {
  if (tcp.isEOF()) {
    console.log('receives complete data');
  }
}

tcp.sockName()

  • Returns: {Object} Local sockaddr.

The tcp.sockName() function shall retrieve the locally-bound name of the specified socket.

Example

var saddr = tcp.sockName();
console.log(saddr);

tcp.peerName()

  • Returns: {Object} Remote sockaddr.

The tcp.peerName() function shall retrieve the peer address of the specified socket.

Example

var saddr = tcp.peerName();
console.log(saddr);

tcp.bindToDevice([ifname])

  • ifname {String} Network interface name. default: all network interface.
  • Returns: {Boolean} Whether the operation was successful.

The tcp.bindToDevice() function binds the network sending and receiving to the specified network interface, and the data packet is only allowed to be sent and received using this network interface.

Example

tcp.bindToDevice('en1');

tcp.setKeepAlive(enable[, idle[, interval[, count]]])

  • enable {Boolean} Whether to enable the keepalive.
  • idle {Integer} The time (in milliseconds) the connection needs to remain idle before TCP starts sending keepalive probes. If enable is true, must have this parameter.
  • interval {Integer} The time (in milliseconds) between individual keepalive probes. default: idle.
  • count {Integer} The maximum number of keepalive probes TCP should send before dropping the connection. default: 3.
  • Returns: {Boolean} Whether the operation was successful.

Keeps connections active by enabling the periodic transmission of messages.

Example

tcp.setKeepAlive(true, 6000);

tcp.setNoDelay(enable)

  • enable {Boolean} Whether to enable the no delay.
  • Returns: {Boolean} Whether the operation was successful.

For TCP NO DEALY, please refer to Nagle's Algorithm and Delayed ACK related articles, which are not described here. If TCP is used for interactive commands, it is recommended to enable.

Example

tcp.setNoDelay(true);

tcp.setLinger(linger)

  • linger {Object} Liger option.
  • Returns: {Boolean} Whether the operation was successful.

linger includes following items:

  • onoff {Boolean} On: true, Off: false:.
  • time {Integer} Linger time expires in seconds.

If linger.onoff is nonzero and linger.time is nonzero, then the kernel will linger when the socket is closed. That is, if there is any data still remaining in the socket send buffer, the process is put to sleep until either: all the data is sent and acknowledged by the peer TCP, or the linger time expires.

Example

tcp.setLinger({ onoff: true, time: 0 });

tcp.setTTL(timeToLive)

  • timeToLive {Integer} IP TTL: 0 ~ 255.
  • Returns: {Boolean} Whether the operation was successful.

Changes the specified tcp TTL value of the IP header.

Example

tcp.setTTL(64);

tcp.setReuseAddr(enable)

  • enable {Boolean} Whether to enable reuse address.
  • Returns: {Boolean} Whether the operation was successful.

Specifies that the rules used in validating addresses supplied to Tcp.createServer() should allow reuse of local addresses. Tcp.createServer() has enabled reuse attribute by default, it is recommended not to disable.

Example

tcp.setReuseAddr(true);

tcp.setIPv6Only(enable)

  • enable {Boolean} Whether to only enable IPv6.
  • Returns: {Boolean} Whether the operation was successful.

If this flag is set to true, then the tcp is re‐stricted to sending and receiving IPv6 packets only.

Example

tcp.setIPv6Only(false);

tcp.getState()

  • Returns: {Integer} TCP state, negative on error.

Get the current TCP object state.

The return value will be one of the following values:

  • socket.TCP_CLOSED
  • socket.TCP_LISTEN
  • socket.TCP_SYN_SENT
  • socket.TCP_SYN_RCVD
  • socket.TCP_ESTABLISHED
  • socket.TCP_FIN_WAIT_1
  • socket.TCP_FIN_WAIT_2
  • socket.TCP_CLOSE_WAIT
  • socket.TCP_CLOSING
  • socket.TCP_LAST_ACK
  • socket.TCP_TIME_WAIT

Example

var state = tcp.getState();

tcp.getRecvBufferSize()

  • Returns: {Integer} Receive buffer size, negative on error.

Get current receive buffer size in bytes.

tcp.getSendBufferSize()

  • Returns: {Integer} Send buffer size, negative on error.

Get current send buffer size in bytes.

tcp.setRecvBufferSize(size)

  • size {Integer} Receive buffer size. Must be between 1024bytes and 16Mbytes.
  • Returns: {Boolean} Whether the operation was successful.

Set current receive buffer size in bytes.

tcp.setSendBufferSize(size)

  • size {Integer} Send buffer size. Must be between 1024bytes and 16Mbytes.
  • Returns: {Boolean} Whether the operation was successful.

Set current send buffer size in bytes.

Synchronous to asynchronous

JSRE provides a synchronous multitasking model. Like other language environments, it also provides an asynchronous processing model. You can choose any way to develop application, even in one application, depending on the characteristics of the different transactions, you can using different methods at one application.

If you are very familiar with asynchronous development, the following method here can convert synchronization to asynchronous.

Server

Example

var EventEmitter = require('events');
var Tcp = require('tcp');
var iosched = require('iosched');

var saddr = Tcp.sockaddr(Tcp.INADDR_ANY, 2049);
var server = Tcp.createServer(saddr);

function onMessage(client, buffer, num) {
  console.log('Client:', client.peerName().addr, 'Say:', buffer.toString(num));
}

server.accept(undefined, (client, remoteAddr) => {
  console.log('New client:', remoteAddr);
  EventEmitter.inherits(client);
  client.on('message', onMessage);
  client.revent = iosched.event(iosched.READ, client.sockFd,
  (client) => {
    var buffer = new Buffer(4096);
    var num = client.recv(buffer);
    if (num > 0) {
      client.emit('message', client, buffer, num);
      return true;
    } else {
      console.log('Client lost:', client.peerName());
      client.close();
      return false;
    }
  }, undefined, client);
  iosched.add(client.revent);
});

while (true) {
  iosched.poll();
}

Client

Example

var EventEmitter = require('events');
var Tcp = require('tcp');
var iosched = require('iosched');

var saddr = Tcp.sockaddr('192.168.0.2', 2049);
var client = Tcp.createClient(saddr, (client) => {
  client.send('Hello I am client ^_^');
  client.send('Goodbye!');
  client.close();
});

while (true) {
  iosched.poll();
}

Multi-Task Server

Example

  • main.js
var Tcp = require('tcp');
var iosched = require('iosched');

// Two Task Server.
var next = 0;
var task = [];
task[0] = new Task('./task.js');
task[1] = new Task('./task.js');

var saddr = Tcp.sockaddr(Tcp.INADDR_ANY, 2049);
var server = Tcp.createServer(saddr);

server.accept(undefined, (client, remoteAddr) => {
  console.log('New client:', remoteAddr);
  // The file descriptor is passed to other tasks and will be closed by other tasks.
  task[next].send({ sockFd: client.sockFd });
  // MUST Call flyAway()
  client.flyAway();
  if (++next > 1) {
    next = 0;
  }
});

while (true) {
  iosched.poll();
}
  • task.js
var EventEmitter = require('events');
var Tcp = require('tcp');
var socket = require('socket');
var iosched = require('iosched');

function onMessage(client, buffer, num) {
  console.log('Client:', client.peerName().addr, 'Say:', buffer.toString(num));
}

Task.on('message', function(msg, from) {
  if (!msg && msg.sockFd < 0) {
    return;
  }
  var client = Tcp.createByFd(msg.sockFd);
  EventEmitter.inherits(client);
  client.on('message', onMessage);
  client.revent = iosched.event(iosched.READ, client.sockFd,
  (client) => {
    var buffer = new Buffer(4096);
    var num = client.recv(buffer);
    if (num > 0) {
      client.emit('message', client, buffer, num);
      return true;
    } else {
      console.log('Client lost:', client.peerName());
      client.close();
      return false;
    }
  }, undefined, client);
  iosched.add(client.revent);
});

iosched.forever();

This demo create a new buffer every time in receive packet. Can you use other methods to reuse buffer?

Tcp Module Constant

Tcp.AF_INET

  • {Integer} 2

Tcp.AF_INET6

  • {Integer} 10

Tcp.INADDR_NONE

  • {String} '255.255.255.255'

Tcp.INADDR_LOOPBACK

  • {String} '127.0.0.1'

Tcp.INADDR_ANY

  • {String} '0.0.0.0'

Tcp.INADDR_BROADCAST

  • {String} '255.255.255.255'

Tcp.IN6ADDR_ANY

  • {String} '::'

Tcp.IN6ADDR_LOOPBACK

  • {String} '::1'

Tcp.IN6ADDR_NODELOCAL_ALLNODES

  • {String} 'ff01::1'

Tcp.IN6ADDR_LINKLOCAL_ALLNODES

  • {String} 'ff02::1'

Tcp.IN6ADDR_LINKLOCAL_ALLROUTERS

  • {String} 'ff01::2'
文档内容是否对您有所帮助?
有帮助
没帮助